using System;
using System.Collections.Generic;
using System.Text;

namespace BetaIto.ChaosDAV.Properties
{
    using System;
    using System.Configuration;
    using System.Xml;
    using System.IO;
    using System.Reflection;
    using System.Collections.Generic;

    public class FixedSettingsConverter
    {
        protected readonly XmlElement _escapeXml = new XmlDocument().CreateElement("temp");

        protected const string XML_NODE_CONFIGURATION = "configuration";
        protected const string XML_NODE_USER_SETTINGS = "userSettings";

        protected const string XML_NODE_SETTING = "setting";
        protected const string XML_NODE_NAME = "name";
        protected const string XML_NODE_SERIALIZE_AS = "serializeAs";
        protected const string XML_NODE_VALUE = "value";

        public string EscapeXmlValue(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            _escapeXml.InnerText = str;
            return _escapeXml.InnerXml;
        }
        public string UnescapeXmlValue(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            _escapeXml.InnerXml = str;
            return _escapeXml.InnerText;
        }

        public virtual XmlDocument ConvertSettingsToXml(IDictionary<string, string> settings, string settingNodeName)
        {
            XmlDocument document = new XmlDocument();
            XmlDeclaration declare = document.CreateXmlDeclaration("1.0", "utf-8", null);
            document.AppendChild(declare);

            XmlNode rootNode = document.CreateElement(XML_NODE_CONFIGURATION);
            XmlElement userElement = document.CreateElement(XML_NODE_USER_SETTINGS);
            XmlElement propElement = document.CreateElement(settingNodeName);

            document.AppendChild(rootNode);
            rootNode.AppendChild(userElement);
            userElement.AppendChild(propElement);

            foreach (KeyValuePair<string, string> setting in settings)
            {
                XmlElement settingElement = document.CreateElement(XML_NODE_SETTING);
                XmlAttribute nameAttr = document.CreateAttribute(XML_NODE_NAME);
                nameAttr.Value = setting.Key;
                XmlAttribute serialAttr = document.CreateAttribute(XML_NODE_SERIALIZE_AS);
                serialAttr.Value = "String";
                XmlElement element = document.CreateElement(XML_NODE_VALUE);
                if (setting.Value != null)
                {
//                    element.InnerXml = setting.Value;
                    element.InnerText = setting.Value;
                }

                settingElement.Attributes.Append(nameAttr);
                settingElement.Attributes.Append(serialAttr);

                settingElement.AppendChild(element);

                propElement.AppendChild(settingElement);
            }
            return document;
        }

        public virtual void ConvertXmlToSettings(XmlDocument document, string settingNodeName, out IDictionary<string, string> settings)
        {
            XmlNode baseNode = document.DocumentElement;
            XmlNode targetNode = null;
            foreach (XmlNode child1 in baseNode.ChildNodes)
            {
                if (child1.Name == XML_NODE_USER_SETTINGS)
                {
                    targetNode = child1;
                    break;
                }
            }
            if (targetNode == null)
            {
                throw new ConfigurationErrorsException(XML_NODE_USER_SETTINGS + " node not found.");
            }
            baseNode = targetNode;
            foreach (XmlNode child1 in baseNode.ChildNodes)
            {
                if (child1.Name == settingNodeName)
                {
                    targetNode = child1;
                    break;
                }
            }
            if (targetNode == null)
            {
                throw new ConfigurationErrorsException(settingNodeName + " node not found.");
            }
            baseNode = targetNode;
            settings = new Dictionary<string, string>();
            foreach (XmlNode child1 in baseNode.ChildNodes)
            {
                if (child1.Name != XML_NODE_SETTING)
                {
                    continue;
                }
                XmlAttribute nameAttr = child1.Attributes[XML_NODE_NAME];
                string keyName = nameAttr.Value;
                if (!child1.HasChildNodes)
                {
                    continue;
                }
                string value = child1.ChildNodes[0].InnerXml;
                value = UnescapeXmlValue(value);
                settings.Add(keyName, value);
            }
        }
    
    }
}
